package top.vanchor.flexible.utils;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import top.vanchor.flexible.config.consts.JwtConst;
import top.vanchor.flexible.config.initexception.BusinessException;
import top.vanchor.flexible.config.initexception.ErrorEnum;
import top.vanchor.flexible.entity.BackAdmin;

import javax.annotation.PostConstruct;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;

/**
 * Created by IntelliJ IDEA.
 *
 * @Author : Ding
 * @create 2022/4/10 11:08
 */
@Component
public class RedisUtils {

    private static final Logger log = LoggerFactory.getLogger(RedisUtils.class);
    @Autowired
    private JedisPool jedisPool;

    private static RedisUtils REDIS_UTILS;

    @Autowired
    private RedisTemplate redisTemplate;


    @PostConstruct
    public void init() {
        REDIS_UTILS = this;
    }

    /**
     * redis缓存token
     *
     * @param admin 用户实体
     * @param token token
     * @return void
     * @Description token的key存储管理员和普通用户角色码，和每个角色对应的id。value存储token内容
     * @Author Ding
     * @date 2022/8/11
     */
    public static void setToken(BackAdmin admin, String token) {
        //创建
        Jedis jedis = REDIS_UTILS.jedisPool.getResource();
        //存储用户token：键格式为【token:CODE:ID】，分别是标识符token、管理员1和用户0的区分CODE和用户ID
        //值格式为String，其实就是token
        //最终如：例如【token:1:1,abc】，即id为1的管理员，其token为abc
        jedis.setex("token:" + 1 + ":" + admin.getAId(), JwtConst.EXPIRE, token);
        //关闭，不然运行运行就会接受不了请求了
        jedis.close();
    }

    /**
     * 判断token是否有效
     *
     * @return boolean
     * @Description 支持单点登录，每次需要token的请求都会被判断是否存在key，同时判断value又是否一致
     * 如果返回0，则正常，如果返回-1，说明不存在；返回-2，说明已在其他地方登录
     * @Author Ding
     * @date 2022/8/11
     */
    public static int isExistsToken() {
        Jedis jedis = null;
        try {
            jedis = REDIS_UTILS.jedisPool.getResource();
            String tokenKey = "token:" + JWTUtils.getAuthorType() + ":" + JWTUtils.getAuthorId();
            for (String key : jedis.keys("token:*")) {
                if (key.equals(tokenKey)) {
                    return JWTUtils.getToken().equals(jedis.get(tokenKey)) ? 0 : -2;
                }
            }
            return -1;
        } catch (Exception e) {
            if (e.getMessage().contains("[B")) {
                throw new BusinessException(ErrorEnum.OPT_TOO_FAST);
            } else {
                try {
                    InetAddress address = InetAddress.getByName("www.baidu.com");
                    Socket socket = new Socket();
                    socket.connect(new InetSocketAddress(address, 80), 5000);
                    e.printStackTrace();
                    log.error("【<Unexpected> 运行时异常】：未可知错误，{}", e.getMessage());
                    throw new BusinessException(ErrorEnum.UNEXPECTED_EXCEPTION);
                } catch (Exception e1) {
                    throw new BusinessException(ErrorEnum.NET_ERR);
                }

            }
        } finally {
            if (jedis != null) {
                jedis.close();
            }
        }
    }

    public static void cacheSmsCode(String phone, String code, Integer second) {
        //创建
        Jedis jedis = REDIS_UTILS.jedisPool.getResource();
        jedis.setex("verifyCode:" + phone, second, code);
        //关闭，不然运行运行就会接受不了请求了
        jedis.close();
    }

    public static String getSmsCode(String phone) {
        Jedis jedis = REDIS_UTILS.jedisPool.getResource();
        String codeKey = "verifyCode:" + phone;
        for (String key : jedis.keys("verifyCode:*")) {
            if (key.equals(codeKey)) {
                jedis.close();
                return jedis.get(codeKey);
            }
        }
        jedis.close();
        return null;
    }


}
